// ProjectName: go-learn-demo
// PackageName: _1_mysql
// Description: 建立对象和数据库表的字段映射关系
// Author: hy.bai
// Date: 2025-08-04 11:32

package gormmysql

import (
	"fmt"
	config "go-learn-demo/08_gorm/00_config"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"log/slog"
	"time"
)

// 建立对象和数据库表的映射关系
// 定义一个结构体，基于结构体去创建表，和对表的CRUD操作。
// 对应的表名是小写复数，即：User对应users
type User struct { // User表的结构体ORM映射
	Id       int32      `json:"id" gorm:"primaryKey;comment:主键"` // gorm:"primaryKey"是gorm框架标签，指定表的主键
	Name     string     `json:"name" gorm:"comment:用户名&姓名"`
	Age      uint8      `json:"age" gorm:"comment:年龄"`
	CreateAt *time.Time `json:"create_time" gorm:"column:create_time;precision:0;autoCreateTime;comment:创建时间"`
	UpdateAt *time.Time `json:"update_time" gorm:"column:update_time;precision:0;autoUpdateTime;comment:最后一次更新时间"`
}

// 自定义表明:实现Tabler接口，重写TableName()方法。
func (user *User) TableName() string {
	return "t_user"
}

// 特点：1.方法名

// 测试创建表
func TestCreateTable() {
	// 1.拼接URL地址
	dns := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		config.MYSQL_USERNAME, config.MYSQL_PWD, config.MYSQL_IP, config.MYSQL_PORT, config.MYSQL_DB)
	// parseTime是查询结果是否自动解析为时间类型,即：time.Time类型，对应的数据库中的类型是：datetime
	// loc是Mysql的时区设置
	// 定义gorm的配置,打印Sql日志
	gConfig := &gorm.Config{
		// Logger: logger.Default.LogMode(logger.Info),
		// DryRun: true, // 默认为false，表示生成SQL语句，而不执行
	}
	// 2.创建Mysql数据库的方言额
	var dialect = mysql.Open(dns)
	db, err := gorm.Open(dialect, gConfig)
	if err != nil {
		message := fmt.Sprintf("failed to connect database. reason:%s", err.Error())
		panic(message) // 抛出Panic异常，终止代码的执行。
	}
	// 2.自动建表,AutoMigrate:自动迁移
	var user *User // 创建User结构体实例，用于后续数据库表的自动创建
	// 默认情况下，创建表时，会自动将结构体的名字转换为复数.
	// 注意:AutoMigrate(user)方法，会判断要创建的表是否存在，如果不存在才会创建
	// db.Set("gorm:table_options", "COMMENT='用户信息表'") // 设置表的选项信息,以添加表注释为例
	if err := db.Set("gorm:table_options", "COMMENT='用户信息表'").AutoMigrate(user); err != nil {
		panic(fmt.Sprintf("创建表失败~,原因是:%s\n", err.Error()))
	}
	slog.Info("Mysql数据库相关操作执行完成~~~")
}
